#include <inctypes.h>
#include <incctrls.h>

/* 初始化 waitlst_t 数据结构 */

void waitlst_t_init 
    (
    waitlst_t * initp
    )
    {

    /* 初始化自旋锁 */

    spinlock_init (&initp->lock);

    /* 初始化链表 */

    list_init (&initp->headlst);

    /* 初始化挂在该等待队列上的对象个数为 0 */

    initp->count = 0;

    return;
    }

/* 把进程加入到相关的 waitlst_t */

void krl_wlst_add_thread
    (
    waitlst_t * wlist,
    thread_t *   thdp
    )
    {
    cpuflg_t    cpuflg;

    /* 等待链表数据结构 自旋锁 上锁 */

    spinlock_saveflg_cli (&wlist->lock, &cpuflg);

    /* 把进程加入 waitlst_t 结构的链表中 */

    list_add (&thdp->list, &wlist->headlst);

    /* 等待链表中的对象 +1 */

    wlist->count++;

    /* 等待链表数据结构 自旋锁 解锁 */

    spinunlock_restflg_sti (&wlist->lock, &cpuflg);

    return;
    }


/* (在表头) 删除 waitlst_t 中的相关进程 */

thread_t * krl_wlst_delete_thread 
    (
    waitlst_t * wlist
    )
    {
    cpuflg_t   cpuflg;
    list_t *   list;
    thread_t * thdp = NULL;

    /* 判断 该等待链表上挂在的对象(进程)个数是否合法 */

    if (wlist->count < 1)
        {
        return NULL;
        }

    /* 等待队列数据结构体加锁 自旋锁 上锁 */

    spinlock_saveflg_cli (&wlist->lock, &cpuflg);

    /* 遍历 wlist->headlst 链表, 每找到一个进程就立即返回 */

    list_for_each (list, &wlist->headlst);
        {
        thdp = list_entry (list, thread_t, list);

        /* 检查结果 */

        if (thdp == NULL)
            {
            thdp = NULL;
            goto return_step;
            }

        /* 把该进程从 wlist->headlst 链表上删除 */

        list_del (&thdp->list);

        /* 挂在的对象(进程)个数 -1 */

        wlist->count--;

        thdp = thdp;

        goto return_step;
        }

    /* 等待队列上未找到等待中的进程 */

    thdp = NULL;

return_step:

    /* 等待队列数据结构体加锁 自旋锁 解锁 */

    spinunlock_restflg_sti (&wlist->lock, &cpuflg);

    return thdp;
    }

/* 唤醒等待队列上的所有进程 */

void krl_wlst_allwakeup 
    (
    waitlst_t * wlist
    )
    {

    /* 遍历等待链表直到链表为空 */
    
    while (list_is_empty_careful (&wlist->headlst) == FALSE) 
        {

        /* 唤醒所有进程 */
        
        krl_sched_up (wlist);
        }

    return;
    }
